import jwt
import datetime
import re
from config import config
from models.user import UserModel

class AuthService:
    """认证服务类 - 业务逻辑层"""
    
    def __init__(self):
        self.user_model = UserModel()
    
    def login(self, username, password):
        """用户登录"""
        # 验证用户名和密码
        if not username or not password:
            return {
                'success': False,
                'message': '用户名和密码不能为空',
                'status_code': 400
            }
        
        # 验证用户凭据
        user = self.user_model.verify_user_credentials(username, password)
        if not user:
            return {
                'success': False,
                'message': '用户名或密码错误',
                'status_code': 401
            }
        
        # 生成JWT token
        token = self.generate_token(username)
        
        return {
            'success': True,
            'message': '登录成功',
            'token': token,
            'user': user,
            'status_code': 200
        }
    
    def generate_token(self, username):
        """生成JWT token"""
        payload = {
            'username': username,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=config.JWT_EXPIRATION_HOURS)
        }
        return jwt.encode(payload, config.SECRET_KEY, algorithm='HS256')
    
    def verify_token(self, token):
        """验证JWT token"""
        try:
            payload = jwt.decode(token, config.SECRET_KEY, algorithms=['HS256'])
            return payload
        except jwt.ExpiredSignatureError:
            return None
        except jwt.InvalidTokenError:
            return None
    
    def get_user_by_token(self, token):
        """根据token获取用户信息"""
        payload = self.verify_token(token)
        if not payload:
            return None
        
        username = payload.get('username')
        return self.user_model.get_user_by_username(username)
    
    def validate_username(self, username):
        """验证用户名格式"""
        if not username:
            return False, '用户名不能为空'
        
        if len(username) < 3 or len(username) > 12:
            return False, '用户名长度必须为3-12个字符'
        
        # 允许字母、数字、下划线
        if not re.match(r'^[a-zA-Z0-9_]+$', username):
            return False, '用户名只能包含字母、数字和下划线'
        
        return True, ''
    
    def validate_password(self, password):
        """验证密码格式"""
        if not password:
            return False, '密码不能为空'
        
        if len(password) < 6 or len(password) > 18:
            return False, '密码长度必须为6-18个字符'
        
        # 只允许英文和数字
        if not re.match(r'^[a-zA-Z0-9]+$', password):
            return False, '密码只能包含英文和数字'
        
        return True, ''
    
    def register(self, username, password, confirm_password):
        """用户注册"""
        # 验证用户名
        is_valid_username, username_error = self.validate_username(username)
        if not is_valid_username:
            return {
                'success': False,
                'message': username_error,
                'status_code': 400
            }
        
        # 验证密码
        is_valid_password, password_error = self.validate_password(password)
        if not is_valid_password:
            return {
                'success': False,
                'message': password_error,
                'status_code': 400
            }
        
        # 验证确认密码
        if password != confirm_password:
            return {
                'success': False,
                'message': '密码和确认密码不一致',
                'status_code': 400
            }
        
        # 调用数据访问层进行注册
        result = self.user_model.register_user(username, password)
        
        if result['success']:
            # 注册成功，生成token
            token = self.generate_token(username)
            
            # 获取用户信息
            user = self.user_model.get_user_by_username(username)
            
            return {
                'success': True,
                'message': '注册成功',
                'token': token,
                'user': {
                    'id': user['id'],
                    'username': user['username'],
                    'nickname': user['nickname']
                },
                'status_code': 201
            }
        else:
            # 注册失败
            return {
                'success': False,
                'message': result['message'],
                'status_code': 400
            }